home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume26 / unproto / part01 next >
Encoding:
Text File  |  1991-12-07  |  53.0 KB  |  2,111 lines

  1. Newsgroups: comp.sources.misc
  2. From: wietse@wzv.win.tue.nl (Wietse Venema)
  3. Subject:  v26i094:  unproto - compile ANSI C with old C compiler, Part01/02
  4. Message-ID: <csm-v26i094=unproto.083344@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 69685c0673793ce6c539657a3d1de2ab
  6. Date: Sun, 1 Dec 1991 14:35:08 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: wietse@wzv.win.tue.nl (Wietse Venema)
  10. Posting-number: Volume 26, Issue 94
  11. Archive-name: unproto/part01
  12. Environment: SYSV2, SunOS
  13. Supersedes: unproto: Volume 23, Issue 12-13
  14.  
  15. This is a filter that sits in between the C preprocessor and the next C
  16. compiler stage, and that on the fly rewrites ANSI C to old C. Its
  17. primary application is to compile ANSI C software in UNIX environments
  18. that do not (yet) have an ANSI C compiler and that cannot run GCC
  19. because of technical or political problems.
  20.  
  21. Problems solved with this release:
  22.  
  23. Minor: the program was originally intended for the compilation of
  24. already tested ANSI C source, so that diagnostics from the native C
  25. compiler would be sufficient. The present release produces better
  26. diagnostics, so that it can also be used for program development.
  27.  
  28. Major: the template Makefile suggested that all #pragma directives be
  29. filtered out. This turns out to be a bad idea because some non-ANSI
  30. compilers (SunOS) rely on #pragmas to correctly handle the unusual flow
  31. control caused by vfork(2), setjmp(3) etcetera. A warning to this
  32. effect has been added to the Makefile.
  33.  
  34. No changes were made to the actual filter logic; output should be
  35. identical to that of the previous release.
  36.  
  37. #! /bin/sh
  38. # This is a shell archive.  Remove anything before this line, then unpack
  39. # it by saving it into a file and typing "sh file".  To overwrite existing
  40. # files, type "sh file -c".  You can also feed this as standard input via
  41. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  42. # will see the following message at the end:
  43. #        "End of archive 1 (of 2)."
  44. # Contents:  Makefile README cpp.sh error.c error.h example.c
  45. #   example.out stdarg.h symbol.c symbol.h tok_class.c tok_io.c
  46. #   tok_pool.c token.h unproto.1 varargs.c vstring.c vstring.h
  47. # Wrapped by wietse@wzv on Sun Dec  1 12:43:04 1991
  48. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  49. if test -f Makefile -a "${1}" != "-c" ; then 
  50.   echo shar: Will not over-write existing file \"Makefile\"
  51. else
  52. echo shar: Extracting \"Makefile\" \(2877 characters\)
  53. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  54. X# @(#) Makefile 1.3 91/12/01 12:37:57
  55. X
  56. X## BEGIN CONFIGURATION STUFF
  57. X
  58. X# For maximal flexibility, the "/lib/cpp | unproto" pipeline can be
  59. X# packaged as an executable shell script (see the provided "cpp.sh" script)
  60. X# that should be installed as "/whatever/cpp". This script should then be
  61. X# specified to the C compiler as a non-default preprocessor.
  62. X#
  63. X# PROG    = unproto
  64. X# PIPE    = 
  65. X
  66. X# For maximal performance, the overhead of shell script inpretation can
  67. X# be eliminated by having the unprototyper program itself open the pipe
  68. X# to the preprocessor.  In that case, define the PIPE_THROUGH_CPP macro
  69. X# as the path name of the default C preprocessor (usually "/lib/cpp"),
  70. X# install the unprototyper as "/whatever/cpp" and specify that to the C
  71. X# compiler as a non-default preprocessor.
  72. X# 
  73. XPROG    = cpp
  74. XPIPE    = -DPIPE_THROUGH_CPP=\"/lib/cpp\"
  75. X
  76. X# Some compilers complain about some #directives. The following is only a 
  77. X# partial solution, because the directives are still seen by /lib/cpp.
  78. X# Be careful with filtering out #pragma, because some non-ANSI compilers
  79. X# (SunOS) rely on its use.
  80. X#
  81. X# SKIP    = -DIGNORE_DIRECTIVES=\"pragma\",\"foo\",\"bar\"
  82. X#
  83. XSKIP    =
  84. X
  85. X# If you need support for functions that implement ANSI-style variable
  86. X# length argument lists, edit the stdarg.h file provided with this
  87. X# package so that it contains the proper definitions for your machine.
  88. X
  89. X## END CONFIGURATION STUFF
  90. X
  91. XSHELL    = /bin/sh
  92. X
  93. XCFILES    = tok_io.c tok_class.c tok_pool.c unproto.c vstring.c symbol.c error.c
  94. XHFILES    = error.h token.h vstring.h symbol.h
  95. XSCRIPTS    = cpp.sh
  96. XSAMPLES    = stdarg.h varargs.c example.c example.out 
  97. XSOURCES    = README Makefile $(CFILES) $(HFILES) $(SCRIPTS) $(SAMPLES)
  98. XFILES    = $(SOURCES) unproto.1
  99. XOBJECTS    = tok_io.o tok_class.o tok_pool.o unproto.o vstring.o symbol.o error.o
  100. X
  101. XCFLAGS    = -O $(PIPE) $(SKIP)
  102. X#CFLAGS    = -O -pg -Dstatic= $(PIPE) $(SKIP)
  103. X#CFLAGS    = -g $(PIPE) $(SKIP) -DDEBUG
  104. X
  105. X$(PROG): $(OBJECTS)
  106. X    cc $(CFLAGS) -o $@ $(OBJECTS) $(MALLOC)
  107. X
  108. X# For linting, enable all bells and whistles.
  109. X
  110. Xlint:
  111. X    lint -DPIPE_THROUGH_CPP=\"foo\" -DIGNORE_DIRECTIVES=\"foo\",\"bar\" \
  112. X    $(CFILES)
  113. X
  114. X# Testing requires that the program is compiled with -DDEBUG
  115. X
  116. Xtest:    $(PROG) example.c example.out
  117. X    ./cpp example.c >example.tmp
  118. X    @echo the following diff command should produce no output
  119. X    diff -b example.out example.tmp
  120. X    rm -f example.tmp
  121. X
  122. Xshar:    $(FILES)
  123. X    @shar $(FILES)
  124. X
  125. Xarchive:
  126. X    $(ARCHIVE) $(SOURCES)
  127. X
  128. Xclean:
  129. X    rm -f *.o core cpp unproto mon.out varargs.o varargs example.tmp
  130. X
  131. Xerror.o : error.c token.h error.h Makefile
  132. Xsymbol.o : symbol.c token.h symbol.h Makefile
  133. Xtok_class.o : tok_class.c error.h vstring.h token.h symbol.h Makefile
  134. Xtok_io.o : tok_io.c token.h vstring.h error.h Makefile
  135. Xtok_pool.o : tok_pool.c token.h vstring.h Makefile
  136. Xunproto.o : unproto.c vstring.h stdarg.h token.h error.h symbol.h Makefile
  137. Xvarargs.o : varargs.c stdarg.h Makefile
  138. Xvstring.o : vstring.c vstring.h Makefile
  139. END_OF_Makefile
  140. if test 2877 -ne `wc -c <Makefile`; then
  141.     echo shar: \"Makefile\" unpacked with wrong size!
  142. fi
  143. # end of overwriting check
  144. fi
  145. if test -f README -a "${1}" != "-c" ; then 
  146.   echo shar: Will not over-write existing file \"README\"
  147. else
  148. echo shar: Extracting \"README\" \(5616 characters\)
  149. sed "s/^X//" >README <<'END_OF_README'
  150. X@(#) README 1.3 91/12/01 12:37:55
  151. X
  152. Xunproto - ANSI C to old C converter
  153. X
  154. XPurpose:
  155. X
  156. XThis is a filter that sits in between the C preprocessor and the next C
  157. Xcompiler stage, and that on the fly rewrites ANSI C to old C. Its
  158. Xprimary application is to compile ANSI C software in UNIX environments
  159. Xthat do not (yet) have an ANSI C compiler and that cannot run GCC
  160. Xbecause of technical or political problems.
  161. X
  162. XThe filter leaves old-style C alone, and de-ANSI-fies function
  163. Xheadings, function pointer type declarations (and casts), function type
  164. Xdeclarations, and combinations thereof. Many freely-distributable
  165. Xunprotoizers have problems with the latter because they are based on a
  166. Xnon-recursive algorithm or even make assumptions about code layout.
  167. X
  168. XThe unprototyper has support for systems that require special tricks
  169. Xfor variadic functions (fortunately, many don't). A sample `stdarg.h'
  170. Xfile is provided with support for sparc, mc68k, 80x86, vax and others.
  171. X
  172. XThe program has been tested on a Sun SLC running SunOS 4.1.1 and on a
  173. X80286 PC clone running Microport's version of System V Release 2. It
  174. Xruns at about the same speed as /lib/cpp, so it should have negigible
  175. Ximpact on compilation times.
  176. X
  177. XProblems solved with this release:
  178. X
  179. XMinor: the program was originally intended for the compilation of
  180. Xalready tested ANSI C source, so that diagnostics from the native C
  181. Xcompiler would be sufficient. The present release produces better
  182. Xdiagnostics, so that it can also be used for program development.
  183. X
  184. XMajor: the template Makefile suggested that all #pragma directives be
  185. Xfiltered out. This turns out to be a bad idea because some non-ANSI
  186. Xcompilers (SunOS) rely on #pragmas to correctly handle the unusual flow
  187. Xcontrol caused by vfork(2), setjmp(3) etcetera. A warning to this
  188. Xeffect has been added to the Makefile.
  189. X
  190. XNo changes were made to the actual filter logic; output should be
  191. Xidentical to that of the previous release.
  192. X
  193. XRestrictions:
  194. X
  195. XOther ANSI-isms are just passed on without modification, such as
  196. Xtrigraphs, token pasting (##), #pragmas, stringizing (#text) and
  197. Xstring concatenation ("string1" "string2").
  198. X
  199. XThe unprototyper does not understand declarations of (object). The
  200. Xresult (the object disappears) will be a syntax error so this should
  201. Xnot go by unnoticed.
  202. X
  203. XSome C programmers rely on ANSI-style prototypes for the automatic type
  204. Xconversion of function arguments.  The unprototyper, however, does not
  205. Xgenerate casts. The lack of automatic conversion between integral
  206. Xand/or pointer argument types should not be a problem in environments
  207. Xwhere sizeof(int) == sizeof(long) == sizeof(pointer).  A more serious
  208. Xproblem is the lack of automatic type conversions beteen integral and
  209. Xfloating-point function argument types.  Let lint(1) be your friend.
  210. X
  211. XOperation:
  212. X
  213. XThis package implements an non-default C preprocessor (the output from
  214. Xthe default C preprocessor being piped through the unprototyper).  How
  215. Xone tells the C compiler to use an non-default preprocessor program is
  216. Xsomewhat compiler-dependent:
  217. X
  218. X    SunOS 4.x:  cc -Qpath directory_with_non-default_cpp ...
  219. X
  220. X    SysV Rel2:  cc -Bdirectory_with_non-default_cpp/ -tp ...
  221. X
  222. XYour C compiler manual should provide the necessary information.
  223. X
  224. XOn some systems the lint(1) command is just a shell script, and writing
  225. Xa version that uses the unprototyper should not be too hard. With SunOS
  226. X4.x, /usr/bin/lint is not a shell script, but it does accept the same
  227. Xsyntax as the cc(1) command for the specification of a non-default
  228. Xcompiler pass. 
  229. X
  230. XYou may have to do some research on the lint command provided with your
  231. Xown machine.
  232. X
  233. XConfiguration:
  234. X
  235. XCheck the contents of the `stdarg.h' file provided with this package.
  236. XThis file serves a dual purpose. It should be included by C source file
  237. Xthat implements ANSI-style variadic functions. It is also used to
  238. Xconfigure the `unproto' program so that it emits the proper magic for
  239. Xthe `...' construct.
  240. X
  241. XThe `stdarg.h' file contains definitions for the sparc architecture and
  242. Xfor architectures that pass arguments via the stack (usually OK for
  243. X80*86, mc68k and vax C compilers).  Risc processors often need special
  244. Xtricks.  These are usually found in the file `/usr/include/varargs.h'.
  245. X
  246. XThe file `varargs.c' provided with this package can be used to verify
  247. Xthat the `stdarg.h' file has been set up correctly.
  248. X
  249. XFor maximal flexibility, you can use the `cpp' shell script provided
  250. Xwith this package to set up the pipe between the default C preprocessor
  251. Xand the unprototyper command. The script assumes that the unprototyper
  252. Xbinary is called `unproto'. See the cpp.sh script and the Makefile for
  253. Xdetails.
  254. X
  255. XThe overhead of shell-script interpretation can be avoided by having
  256. Xthe unprototyper itself open the pipe to the C preprocessor.  In this
  257. Xcase, the `unproto.c' source file should be compiled with the
  258. X`PIPE_THROUGH_CPP' macro defined as the pathname of the C preprocessor
  259. X(usually `/lib/cpp'), and the unprototyper binary should be called
  260. X`cpp'.  See the Makefile for details.
  261. X
  262. XInstallation:
  263. X
  264. XInstall the `stdarg.h' include file and the `unproto.1' manual page in
  265. Xsuitable places.
  266. X
  267. XIf you use the `cpp' shell script to pipe the preprocessor output
  268. Xthrough the unprototyper program, install the `unproto' binary in a
  269. Xplace where the `cpp' shell script can find it, and install the `cpp'
  270. Xshell script in a suitable place.
  271. X
  272. XIf the unprototyper itself opens the pipe to the C preprocessor (i.e.
  273. Xthe unprototyper was built with the `PIPE_THROUGH_CPP' macro defined),
  274. Xinstall the `cpp' unprototyper binary in a suitable place.
  275. X
  276. X    Wietse Venema
  277. X    wietse@wzv.win.tue.nl
  278. X    Eindhoven University of Technology
  279. X    The Netherlands
  280. END_OF_README
  281. if test 5616 -ne `wc -c <README`; then
  282.     echo shar: \"README\" unpacked with wrong size!
  283. fi
  284. # end of overwriting check
  285. fi
  286. if test -f cpp.sh -a "${1}" != "-c" ; then 
  287.   echo shar: Will not over-write existing file \"cpp.sh\"
  288. else
  289. echo shar: Extracting \"cpp.sh\" \(311 characters\)
  290. sed "s/^X//" >cpp.sh <<'END_OF_cpp.sh'
  291. X#!/bin/sh
  292. X
  293. X# @(#) cpp.sh 1.2 91/09/22 21:21:43
  294. X
  295. X# Unprototypeing preprocessor for non-ANSI C compilers. Define __STDC__
  296. X# if you have enough courage. You will have to modify this script if
  297. X# your cc(1) command specifies output file names to the preprocessor.
  298. X
  299. Xexec /lib/cpp "$@" -Dconst= -Dvolatile= | unproto 
  300. END_OF_cpp.sh
  301. if test 311 -ne `wc -c <cpp.sh`; then
  302.     echo shar: \"cpp.sh\" unpacked with wrong size!
  303. fi
  304. # end of overwriting check
  305. fi
  306. if test -f error.c -a "${1}" != "-c" ; then 
  307.   echo shar: Will not over-write existing file \"error.c\"
  308. else
  309. echo shar: Extracting \"error.c\" \(1675 characters\)
  310. sed "s/^X//" >error.c <<'END_OF_error.c'
  311. X/*++
  312. X/* NAME
  313. X/*    error 3
  314. X/* SUMMARY
  315. X/*    diagnostics
  316. X/* PACKAGE
  317. X/*    unproto
  318. X/* SYNOPSIS
  319. X/*    #include "error.h"
  320. X/*
  321. X/*    void error(quit, text)
  322. X/*    int quit;
  323. X/*    char *text;
  324. X/*
  325. X/*    void error_where(quit, path, line, text)
  326. X/*    int quit;
  327. X/*    char *path;
  328. X/*    int line;
  329. X/*    char *text;
  330. X/* DESCRIPTION
  331. X/*    The routines in this file print a diagnostic (text) and optionally
  332. X/*    terminate the program (quit != 0) with exit status "quit".
  333. X/*
  334. X/*    error() provides a default context, i.e. the source-file
  335. X/*    coordinate of the last read token.
  336. X/*
  337. X/*    error_where() allows the caller to explicitly specify context: path
  338. X/*    is a source-file name, and line is a line number.
  339. X/*
  340. X/*    context is ignored if the line number is zero or if the path
  341. X/*    is an empty string.
  342. X/* AUTHOR(S)
  343. X/*    Wietse Venema
  344. X/*    Eindhoven University of Technology
  345. X/*    Department of Mathematics and Computer Science
  346. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  347. X/* LAST MODIFICATION
  348. X/*    91/11/30 21:10:35
  349. X/* VERSION/RELEASE
  350. X/*    1.1
  351. X/*--*/
  352. X
  353. Xstatic char error_sccsid[] = "@(#) error.c 1.1 91/11/30 21:10:35";
  354. X
  355. X/* C library */
  356. X
  357. X#include <stdio.h>
  358. X
  359. Xvoid exit();
  360. X
  361. X/* Application-specific stuff */
  362. X
  363. X#include "token.h"
  364. X#include "error.h"
  365. X
  366. X/* error - report problem (implicit context) and optionally quit */
  367. X
  368. Xvoid    error(quit, text)
  369. Xint     quit;
  370. Xchar   *text;
  371. X{
  372. X    error_where(quit, curr_path, curr_line, text);
  373. X}
  374. X
  375. X/* error_where - report problem (explicit context) and optionally quit */
  376. X
  377. Xvoid    error_where(quit, path, line, text)
  378. Xint     quit;
  379. Xchar   *path;
  380. Xint     line;
  381. Xchar   *text;
  382. X{
  383. X    if (line && path[0])
  384. X    fprintf(stderr, "%s, line %d: ", path, line);
  385. X    fprintf(stderr, "%s\n", text);
  386. X    if (quit)
  387. X    exit(quit);
  388. X}
  389. END_OF_error.c
  390. if test 1675 -ne `wc -c <error.c`; then
  391.     echo shar: \"error.c\" unpacked with wrong size!
  392. fi
  393. # end of overwriting check
  394. fi
  395. if test -f error.h -a "${1}" != "-c" ; then 
  396.   echo shar: Will not over-write existing file \"error.h\"
  397. else
  398. echo shar: Extracting \"error.h\" \(144 characters\)
  399. sed "s/^X//" >error.h <<'END_OF_error.h'
  400. X/* @(#) error.h 1.1 91/11/30 21:10:36 */
  401. X
  402. Xextern void error();            /* default context */
  403. Xextern void error_where();        /* user-specified context */
  404. END_OF_error.h
  405. if test 144 -ne `wc -c <error.h`; then
  406.     echo shar: \"error.h\" unpacked with wrong size!
  407. fi
  408. # end of overwriting check
  409. fi
  410. if test -f example.c -a "${1}" != "-c" ; then 
  411.   echo shar: Will not over-write existing file \"example.c\"
  412. else
  413. echo shar: Extracting \"example.c\" \(2062 characters\)
  414. sed "s/^X//" >example.c <<'END_OF_example.c'
  415. X /*
  416. X  * @(#) example.c 1.2 91/09/22 21:21:45
  417. X  * 
  418. X  * Examples of things that can be done with the unproto package
  419. X  */
  420. X
  421. X /*
  422. X  * New-style argument list with structured argument, one field being pointer
  423. X  * to function returning pointer to function with function-pointer argument
  424. X  */
  425. X
  426. Xx(struct {
  427. X    struct {
  428. X    int (*(*foo) (int (*arg1) (double))) (float arg2);
  429. X    } foo;
  430. X} baz) {
  431. X    return (0);
  432. X}
  433. X
  434. X /*
  435. X  * Old-style argument list with new-style argument type, declaration
  436. X  * embedded within block. Plus a couple assignments with function calls that
  437. X  * look like casts.
  438. X  */
  439. X
  440. Xfoo(bar)
  441. Xint     (*(*bar) (float)) (int);
  442. X{
  443. X    int     (*baz) (int) = (int (*) (int)) 0,
  444. X        y = (y * (*baz) (y)),
  445. X        *(*z) (int) = (int *(*) (int)) 0;
  446. X
  447. X    struct { int (*foo)(int); } *(*s)(int) = 
  448. X    (struct { int (*foo)(int); } *(*)(int)) 0;
  449. X
  450. X    {
  451. X    y = (y * (*baz) (y));
  452. X    }
  453. X    {
  454. X    z = (int *(*) (int)) 0;
  455. X    }
  456. X    {
  457. X    s = (struct { int (*foo)(int); } *(*)(int)) 0;
  458. X    }
  459. X
  460. X    return (0);
  461. X}
  462. X
  463. X/* Multiple declarations in one statement */
  464. X
  465. Xtest1()
  466. X{
  467. X    int foo2,*(*(*bar)(int))(float),*baz(double);
  468. X}
  469. X
  470. X/* Discriminate declarations from executable statements */
  471. X
  472. Xtest2(char *y)
  473. X{
  474. X    int foo = 5,atoi(char *);
  475. X
  476. X    foo = 5,atoi(y);
  477. X}
  478. X
  479. X/* Declarations without explicit type */
  480. X
  481. Xtest3,test4(int);
  482. X
  483. Xtest5(int y)
  484. X{
  485. X    {
  486. X        test3;
  487. X    }
  488. X    {
  489. X        test4(y);
  490. X    }
  491. X}
  492. X
  493. Xtest6[1],test7(int);
  494. X
  495. Xtest7(int x)
  496. X{
  497. X    {
  498. X        test6[1];
  499. X    }
  500. X    {
  501. X        test7(x);
  502. X    }
  503. X}
  504. X
  505. X/* Checking a complicated cast */
  506. X
  507. Xstruct {
  508. X    struct {
  509. X    int (*f)(int), o;
  510. X    } bar;
  511. X} (*baz2)(int) = (struct { struct { int (*f)(int), o; } bar; } (*)(int)) 0;
  512. X
  513. X/* Distinguish things with the same shape but with different meaning */
  514. X
  515. Xtest8(x)
  516. X{
  517. X    {
  518. X    struct {
  519. X        int     foo;
  520. X    } bar(int);
  521. X    }
  522. X    {
  523. X    do {
  524. X        int     foo;
  525. X    } while (x);
  526. X    }
  527. X}
  528. X
  529. X/* Do not think foo(*bar) is a function pointer declaration */
  530. X
  531. Xtest9(char *bar)
  532. X{
  533. X    foo(*bar);
  534. X}
  535. X
  536. X/* another couple of special-cased words. */
  537. X
  538. Xtest10(int x)
  539. X{
  540. X    {
  541. X    int test10(int);
  542. X    do  test10(x);
  543. X    while (x);
  544. X    }
  545. X    {
  546. X    return test10(x);
  547. X    }
  548. X}
  549. X
  550. Xtest11(int *x)
  551. X{
  552. X    while (*x)
  553. X        (putchar(*x++));
  554. X}
  555. END_OF_example.c
  556. if test 2062 -ne `wc -c <example.c`; then
  557.     echo shar: \"example.c\" unpacked with wrong size!
  558. fi
  559. # end of overwriting check
  560. fi
  561. if test -f example.out -a "${1}" != "-c" ; then 
  562.   echo shar: Will not over-write existing file \"example.out\"
  563. else
  564. echo shar: Extracting \"example.out\" \(1994 characters\)
  565. sed "s/^X//" >example.out <<'END_OF_example.out'
  566. X# 1 "example.c" 
  567. X
  568. X
  569. X
  570. X
  571. X
  572. X
  573. X
  574. X
  575. X
  576. Xx
  577. X
  578. X
  579. X
  580. X(baz)
  581. X# 16 "example.c"
  582. Xstruct {    struct {    int (*(*foo)())();    } foo;} baz;
  583. X# 16 "example.c"
  584. X{/*1*/
  585. X    /* end dcls */return (0);
  586. X}/*1*/
  587. X
  588. X
  589. X
  590. X
  591. X
  592. X
  593. Xfoo
  594. X(bar)int     (*(*bar)())();
  595. X{/*1*/
  596. X    int     (*baz)() = (int (*)()) 0,
  597. X        y = (y * (*baz)(y)),
  598. X        *(*z)() = (int *(*)()) 0;
  599. X
  600. X    struct {/*2*/ int (*foo)(); }/*2*/ *(*s)() = 
  601. X    (struct { int (*foo)(); } *(*)()) 0;
  602. X
  603. X    /* end dcls */{/*2*/
  604. X    y /* end dcls */= (y * (*baz)(y));
  605. X    }/*2*/
  606. X    {/*2*/
  607. X    z /* end dcls */= (int *(*)()) 0;
  608. X    }/*2*/
  609. X    {/*2*/
  610. X    s /* end dcls */= (struct { int (*foo)(); } *(*)()) 0;
  611. X    }/*2*/
  612. X
  613. X    return (0);
  614. X}/*1*/
  615. X
  616. X
  617. X
  618. Xtest1
  619. X()
  620. X# 52 "example.c"
  621. X{/*1*/
  622. X    int foo2,*(*(*bar)())(),*baz();
  623. X}/*1*/
  624. X
  625. X
  626. X
  627. Xtest2
  628. X(y)
  629. X# 59 "example.c"
  630. Xchar *y;
  631. X# 59 "example.c"
  632. X{/*1*/
  633. X    int foo = 5,atoi();
  634. X
  635. X    foo /* end dcls */= 5,atoi(y);
  636. X}/*1*/
  637. X
  638. X
  639. X
  640. Xtest3,test4();
  641. X
  642. Xtest5
  643. X(y)
  644. X# 70 "example.c"
  645. Xint y;
  646. X# 70 "example.c"
  647. X{/*1*/
  648. X    /* end dcls */{/*2*/
  649. X        test3/* end dcls */;
  650. X    }/*2*/
  651. X    {/*2*/
  652. X        test4/* end dcls */(y);
  653. X    }/*2*/
  654. X}/*1*/
  655. X
  656. Xtest6[1],test7();
  657. X
  658. Xtest7
  659. X(x)
  660. X# 82 "example.c"
  661. Xint x;
  662. X# 82 "example.c"
  663. X{/*1*/
  664. X    /* end dcls */{/*2*/
  665. X        test6/* end dcls */[1];
  666. X    }/*2*/
  667. X    {/*2*/
  668. X        test7/* end dcls */(x);
  669. X    }/*2*/
  670. X}/*1*/
  671. X
  672. X
  673. X
  674. Xstruct {/*1*/
  675. X    struct {/*2*/
  676. X    int (*f)(), o;
  677. X    }/*2*/ bar;
  678. X}/*1*/ (*baz2)() = (struct { struct { int (*f)(), o; } bar; } (*)()) 0;
  679. X
  680. X
  681. X
  682. Xtest8
  683. X(x)
  684. X# 102 "example.c"
  685. X{/*1*/
  686. X    /* end dcls */{/*2*/
  687. X    struct {/*3*/
  688. X        int     foo;
  689. X    }/*3*/ bar();
  690. X    }/*2*/
  691. X    {/*2*/
  692. X    /* end dcls */do {/*3*/
  693. X        int     foo;
  694. X    }/*3*/ while (x);
  695. X    }/*2*/
  696. X}/*1*/
  697. X
  698. X
  699. X
  700. Xtest9
  701. X(bar)
  702. X# 118 "example.c"
  703. Xchar *bar;
  704. X# 118 "example.c"
  705. X{/*1*/
  706. X    foo/* end dcls */(*bar);
  707. X}/*1*/
  708. X
  709. X
  710. X
  711. Xtest10
  712. X(x)
  713. X# 125 "example.c"
  714. Xint x;
  715. X# 125 "example.c"
  716. X{/*1*/
  717. X    /* end dcls */{/*2*/
  718. X    int test10();
  719. X    /* end dcls */do  test10(x);
  720. X    while (x);
  721. X    }/*2*/
  722. X    {/*2*/
  723. X    /* end dcls */return test10(x);
  724. X    }/*2*/
  725. X}/*1*/
  726. X
  727. Xtest11
  728. X(x)
  729. X# 137 "example.c"
  730. Xint *x;
  731. X# 137 "example.c"
  732. X{/*1*/
  733. X    /* end dcls */while (*x)
  734. X        (putchar(*x++));
  735. X}/*1*/
  736. END_OF_example.out
  737. if test 1994 -ne `wc -c <example.out`; then
  738.     echo shar: \"example.out\" unpacked with wrong size!
  739. fi
  740. # end of overwriting check
  741. fi
  742. if test -f stdarg.h -a "${1}" != "-c" ; then 
  743.   echo shar: Will not over-write existing file \"stdarg.h\"
  744. else
  745. echo shar: Extracting \"stdarg.h\" \(1413 characters\)
  746. sed "s/^X//" >stdarg.h <<'END_OF_stdarg.h'
  747. X /*
  748. X  * @(#) stdarg.h 1.2 91/11/30 21:10:39
  749. X  * 
  750. X  * Sample stdarg.h file for use with the unproto filter.
  751. X  * 
  752. X  * This file serves two purposes.
  753. X  * 
  754. X  * 1 - As an include file for use with ANSI-style C source that implements
  755. X  * variadic functions.
  756. X  * 
  757. X  * 2 - To configure the unproto filter itself. If the _VA_ALIST_ macro is
  758. X  * defined, its value will appear in the place of the "..." in argument
  759. X  * lists of variadic function *definitions* (not declarations).
  760. X  * 
  761. X  * Compilers that pass arguments via the stack can use the default code at the
  762. X  * end of this file (this usually applies for the VAX, MC68k and 80*86
  763. X  * architectures).
  764. X  * 
  765. X  * RISC-based systems often need special tricks. An example of the latter is
  766. X  * given for the SPARC architecture. Read your /usr/include/varargs.h for
  767. X  * more information.
  768. X  * 
  769. X  * You can use the varargs.c program provided with the unproto package to
  770. X  * verify that the stdarg.h file has been set up correctly.
  771. X  */
  772. X
  773. X#ifdef sparc
  774. X#  define _VA_ALIST_        "__builtin_va_alist"
  775. X   typedef char *va_list;
  776. X#  define va_start(ap, p)    (ap = (char *) &__builtin_va_alist)
  777. X#  define va_arg(ap, type)    ((type *) __builtin_va_arg_incr((type *) ap))[0]
  778. X#  define va_end(ap)
  779. X#else /* vax, mc68k, 80*86 */
  780. X   typedef char *va_list;
  781. X#  define va_start(ap, p)    (ap = (char *) (&(p)+1))
  782. X#  define va_arg(ap, type)    ((type *) (ap += sizeof(type)))[-1]
  783. X#  define va_end(ap)
  784. X#endif
  785. END_OF_stdarg.h
  786. if test 1413 -ne `wc -c <stdarg.h`; then
  787.     echo shar: \"stdarg.h\" unpacked with wrong size!
  788. fi
  789. # end of overwriting check
  790. fi
  791. if test -f symbol.c -a "${1}" != "-c" ; then 
  792.   echo shar: Will not over-write existing file \"symbol.c\"
  793. else
  794. echo shar: Extracting \"symbol.c\" \(3522 characters\)
  795. sed "s/^X//" >symbol.c <<'END_OF_symbol.c'
  796. X/*++
  797. X/* NAME
  798. X/*    symbol 3
  799. X/* SUMMARY
  800. X/*    rudimentary symbol table package
  801. X/* SYNOPSIS
  802. X/*    #include "symbol.h"
  803. X/*
  804. X/*    void sym_init()
  805. X/*
  806. X/*    void sym_enter(name, type)
  807. X/*    char *name;
  808. X/*    int type;
  809. X/*
  810. X/*    struct symbol *sym_find(name)
  811. X/*    char *name;
  812. X/* DESCRIPTION
  813. X/*    This is a rudimentary symbol-table package, just enough to
  814. X/*    keep track of a couple of C keywords.
  815. X/*
  816. X/*    sym_init() primes the table with C keywords. At present, most of
  817. X/*    the keywords that have to do with types are left out.
  818. X/*    We need a different strategy to detect type definitions because
  819. X/*    we do not keep track of typedef names.
  820. X/*
  821. X/*    sym_enter() adds an entry to the symbol table.
  822. X/*
  823. X/*    sym_find() locates a symbol table entry (it returns 0 if
  824. X/*    it is not found).
  825. X/* AUTHOR(S)
  826. X/*    Wietse Venema
  827. X/*    Eindhoven University of Technology
  828. X/*    Department of Mathematics and Computer Science
  829. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  830. X/* LAST MODIFICATION
  831. X/*    91/11/30 21:10:33
  832. X/* VERSION/RELEASE
  833. X/*    1.2
  834. X/*--*/
  835. X
  836. Xstatic char symbol_sccsid[] = "@(#) symbol.c 1.2 91/11/30 21:10:33";
  837. X
  838. X/* C library */
  839. X
  840. Xextern char *strcpy();
  841. Xextern char *malloc();
  842. X
  843. X/* Application-specific stuff */
  844. X
  845. X#include "error.h"
  846. X#include "token.h"
  847. X#include "symbol.h"
  848. X
  849. X#define    SYM_TABSIZE    20
  850. X
  851. Xstatic struct symbol *sym_tab[SYM_TABSIZE] = {0,};
  852. X
  853. X/* More string stuff. Maybe it should go to an #include file. */
  854. X
  855. X#define    STREQ(x,y)    (*(x) == *(y) && strcmp((x),(y)) == 0)
  856. X
  857. X/* hash - hash a string; original author: P. J. Weinberger at Bell Labs. */
  858. X
  859. Xstatic unsigned hash(s, size)
  860. Xregister char *s;
  861. Xunsigned size;
  862. X{
  863. X    register unsigned long h = 0;
  864. X    register unsigned long g;
  865. X
  866. X    /*
  867. X     * For a performance comparison with the hash function presented in K&R,
  868. X     * first edition, see the "Dragon" book by Aho, Sethi and Ullman.
  869. X     */
  870. X
  871. X    while (*s) {
  872. X    h = (h << 4) + *s++;
  873. X    if (g = (h & 0xf0000000)) {
  874. X        h ^= (g >> 24);
  875. X        h ^= g;
  876. X    }
  877. X    }
  878. X    return (h % size);
  879. X}
  880. X
  881. X/* sym_enter - enter symbol into table */
  882. X
  883. Xvoid    sym_enter(name, type)
  884. Xchar   *name;
  885. Xint     type;
  886. X{
  887. X    struct symbol *s;
  888. X    int     where;
  889. X
  890. X    if ((s = (struct symbol *) malloc(sizeof(*s))) == 0
  891. X    || (s->name = malloc(strlen(name) + 1)) == 0)
  892. X    error(1, "out of memory");
  893. X    (void) strcpy(s->name, name);
  894. X    s->type = type;
  895. X
  896. X    where = hash(name, SYM_TABSIZE);
  897. X    s->next = sym_tab[where];
  898. X    sym_tab[where] = s;
  899. X}
  900. X
  901. X/* sym_find - locate symbol definition */
  902. X
  903. Xstruct symbol *sym_find(name)
  904. Xregister char *name;
  905. X{
  906. X    register struct symbol *s;
  907. X
  908. X    /*
  909. X     * This function is called for almost every "word" token, so it better be
  910. X     * fast.
  911. X     */
  912. X
  913. X    for (s = sym_tab[hash(name, SYM_TABSIZE)]; s; s = s->next)
  914. X    if (STREQ(name, s->name))
  915. X        return (s);
  916. X    return (0);
  917. X}
  918. X
  919. X /*
  920. X  * Initialization data for symbol table. We do not enter keywords for types.
  921. X  * We use a different strategy to detect type declarations because we do not
  922. X  * keep track of typedef names.
  923. X  */
  924. X
  925. Xstruct sym {
  926. X    char   *name;
  927. X    int     tokno;
  928. X};
  929. X
  930. Xstatic struct sym syms[] = {
  931. X    "if", TOK_CONTROL,
  932. X    "else", TOK_CONTROL,
  933. X    "while", TOK_CONTROL,
  934. X    "do", TOK_CONTROL,
  935. X    "switch", TOK_CONTROL,
  936. X    "case", TOK_CONTROL,
  937. X    "default", TOK_CONTROL,
  938. X    "return", TOK_CONTROL,
  939. X    "continue", TOK_CONTROL,
  940. X    "break", TOK_CONTROL,
  941. X    "goto", TOK_CONTROL,
  942. X    "struct", TOK_COMPOSITE,
  943. X    "union", TOK_COMPOSITE,
  944. X    0,
  945. X};
  946. X
  947. X/* sym_init - enter known keywords into symbol table */
  948. X
  949. Xvoid    sym_init()
  950. X{
  951. X    register struct sym *p;
  952. X
  953. X    for (p = syms; p->name; p++)
  954. X    sym_enter(p->name, p->tokno);
  955. X}
  956. X
  957. END_OF_symbol.c
  958. if test 3522 -ne `wc -c <symbol.c`; then
  959.     echo shar: \"symbol.c\" unpacked with wrong size!
  960. fi
  961. # end of overwriting check
  962. fi
  963. if test -f symbol.h -a "${1}" != "-c" ; then 
  964.   echo shar: Will not over-write existing file \"symbol.h\"
  965. else
  966. echo shar: Extracting \"symbol.h\" \(318 characters\)
  967. sed "s/^X//" >symbol.h <<'END_OF_symbol.h'
  968. X/* @(#) symbol.h 1.1 91/09/22 21:21:42 */
  969. X
  970. Xstruct symbol {
  971. X    char   *name;            /* symbol name */
  972. X    int     type;            /* symbol type */
  973. X    struct symbol *next;
  974. X};
  975. X
  976. Xextern void sym_enter();        /* add symbol to table */
  977. Xextern struct symbol *sym_find();    /* locate symbol */
  978. Xextern void sym_init();            /* prime the table */
  979. END_OF_symbol.h
  980. if test 318 -ne `wc -c <symbol.h`; then
  981.     echo shar: \"symbol.h\" unpacked with wrong size!
  982. fi
  983. # end of overwriting check
  984. fi
  985. if test -f tok_class.c -a "${1}" != "-c" ; then 
  986.   echo shar: Will not over-write existing file \"tok_class.c\"
  987. else
  988. echo shar: Extracting \"tok_class.c\" \(4091 characters\)
  989. sed "s/^X//" >tok_class.c <<'END_OF_tok_class.c'
  990. X/*++
  991. X/* NAME
  992. X/*    tok_class 3
  993. X/* SUMMARY
  994. X/*    token classification
  995. X/* PACKAGE
  996. X/*    unproto
  997. X/* SYNOPSIS
  998. X/*    #include "token.h"
  999. X/*
  1000. X/*    struct token *tok_class(skip)
  1001. X/*    int skip;
  1002. X/* DESCRIPTION
  1003. X/*    tok_class() collects a single and composite tokens, and
  1004. X/*    recognizes keywords.
  1005. X/*    At present, the only composite tokens are ()-delimited,
  1006. X/*    comma-separated lists.
  1007. X/*
  1008. X/*    The skip argument has the same meaning as with the tok_get()
  1009. X/*    function.
  1010. X/* DIAGNOSTICS
  1011. X/*    The code complains if input terminates in the middle of a list.
  1012. X/* BUGS
  1013. X/*    Does not preserve white space at the beginning of a list element
  1014. X/*    or after the end of a list.
  1015. X/* AUTHOR(S)
  1016. X/*    Wietse Venema
  1017. X/*    Eindhoven University of Technology
  1018. X/*    Department of Mathematics and Computer Science
  1019. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1020. X/* LAST MODIFICATION
  1021. X/*    91/11/30 21:10:28
  1022. X/* VERSION/RELEASE
  1023. X/*    1.3
  1024. X/*--*/
  1025. X
  1026. Xstatic char class_sccsid[] = "@(#) tok_class.c 1.3 91/11/30 21:10:28";
  1027. X
  1028. X/* C library */
  1029. X
  1030. X#include <stdio.h>
  1031. X
  1032. Xextern char *strcpy();
  1033. X
  1034. X/* Application-specific stuff */
  1035. X
  1036. X#include "error.h"
  1037. X#include "vstring.h"
  1038. X#include "token.h"
  1039. X#include "symbol.h"
  1040. X
  1041. Xstatic struct token *tok_list();
  1042. Xstatic void tok_list_struct();
  1043. Xstatic void tok_list_append();
  1044. X
  1045. X/* tok_space_append - append trailing space except after list */
  1046. X
  1047. X#define    tok_space_append(list,t) { \
  1048. X                    if (list == 0     /* leading space*/ \
  1049. X                    || list->tokno == TOK_LIST) \
  1050. X                    tok_free(t); \
  1051. X                    else \
  1052. X                    tok_list_append(list, t); \
  1053. X                }
  1054. X
  1055. X/* tok_class - discriminate single tokens, keywords, and composite tokens */
  1056. X
  1057. Xstruct token *tok_class(skip)
  1058. Xint     skip;
  1059. X{
  1060. X    register struct token *t;
  1061. X    register struct symbol *s;
  1062. X
  1063. X    if (t = tok_get(skip)) {
  1064. X    switch (t->tokno) {
  1065. X    case '(':                /* beginning of list */
  1066. X        t = tok_list(t);
  1067. X        break;
  1068. X    case TOK_WORD:                /* look up keyword */
  1069. X        if (s = sym_find(t->vstr->str))
  1070. X        t->tokno = s->type;
  1071. X        break;
  1072. X    }
  1073. X    }
  1074. X    return (t);
  1075. X}
  1076. X
  1077. X/* tok_list - collect ()-delimited, comma-separated list of tokens */
  1078. X
  1079. Xstatic struct token *tok_list(t)
  1080. Xstruct token *t;
  1081. X{
  1082. X    register struct token *list = tok_alloc();
  1083. X    char    filename[BUFSIZ];
  1084. X    int     lineno;
  1085. X
  1086. X    /* Save context of '(' for diagnostics. */
  1087. X
  1088. X    strcpy(filename, curr_path);
  1089. X    lineno = curr_line;
  1090. X
  1091. X    list->tokno = TOK_LIST;
  1092. X    list->head = list->tail = t;
  1093. X#ifdef DEBUG
  1094. X    strcpy(list->vstr->str, "LIST");
  1095. X#endif
  1096. X
  1097. X    for (;;) {
  1098. X    if ((t = tok_get(DO_WSPACE)) == 0) {    /* skip blanks */
  1099. X        error_where(0, filename, lineno, "unmatched '('");
  1100. X        return (list);            /* do not waste any data */
  1101. X    }
  1102. X    switch (t->tokno) {
  1103. X    case ')':                /* end of list */
  1104. X        tok_free(t);
  1105. X        return (list);
  1106. X    case '{':                /* struct/union type */
  1107. X        tok_list_struct(list->tail, t);
  1108. X        break;
  1109. X    case TOK_WSPACE:            /* preserve trailing blanks */
  1110. X        tok_space_append(list->tail->tail, t);    /* except after list */
  1111. X        break;
  1112. X    case '\n':                /* preserve line count */
  1113. X        tok_flush(t);
  1114. X        break;
  1115. X    case ',':                /* list separator */
  1116. X        tok_list_append(list, t);
  1117. X        break;
  1118. X    case '(':                /* beginning of list */
  1119. X        tok_list_append(list->tail, tok_list(t));
  1120. X        break;
  1121. X    default:                /* ordinary token */
  1122. X        tok_list_append(list->tail, t);
  1123. X        break;
  1124. X    }
  1125. X    }
  1126. X}
  1127. X
  1128. X/* tok_list_struct - collect structured type info within list */
  1129. X
  1130. Xstatic void tok_list_struct(list, t)
  1131. Xregister struct token *list;
  1132. Xregister struct token *t;
  1133. X{
  1134. X    tok_list_append(list, t);
  1135. X
  1136. X    while (t = tok_class(DO_WSPACE)) {
  1137. X    switch (t->tokno) {
  1138. X    case '\n':                /* preserve line count */
  1139. X        tok_flush(t);
  1140. X        break;
  1141. X    case TOK_WSPACE:            /* preserve trailing blanks */
  1142. X        tok_space_append(list->tail, t);    /* except after list */
  1143. X        break;
  1144. X    case '{':                /* recurse */
  1145. X        tok_list_struct(list, t);
  1146. X        break;
  1147. X    case '}':                /* done */
  1148. X        tok_list_append(list, t);
  1149. X        return;
  1150. X    default:                /* other */
  1151. X        tok_list_append(list, t);
  1152. X        break;
  1153. X    }
  1154. X    }
  1155. X}
  1156. X
  1157. X/* tok_list_append - append data to list */
  1158. X
  1159. Xstatic void tok_list_append(h, t)
  1160. Xstruct token *h;
  1161. Xstruct token *t;
  1162. X{
  1163. X    if (h->head == 0) {
  1164. X    h->head = h->tail = t;
  1165. X    } else {
  1166. X    h->tail->next = t;
  1167. X    h->tail = t;
  1168. X    }
  1169. X}
  1170. END_OF_tok_class.c
  1171. if test 4091 -ne `wc -c <tok_class.c`; then
  1172.     echo shar: \"tok_class.c\" unpacked with wrong size!
  1173. fi
  1174. # end of overwriting check
  1175. fi
  1176. if test -f tok_io.c -a "${1}" != "-c" ; then 
  1177.   echo shar: Will not over-write existing file \"tok_io.c\"
  1178. else
  1179. echo shar: Extracting \"tok_io.c\" \(9985 characters\)
  1180. sed "s/^X//" >tok_io.c <<'END_OF_tok_io.c'
  1181. X/*++
  1182. X/* NAME
  1183. X/*    tok_io 3
  1184. X/* SUMMARY
  1185. X/*    token I/O
  1186. X/* PACKAGE
  1187. X/*    unproto
  1188. X/* SYNOPSIS
  1189. X/*    #include "token.h"
  1190. X/*
  1191. X/*    struct token *tok_get(skip_flag)
  1192. X/*    int skip_flag;
  1193. X/*
  1194. X/*    void tok_unget(t)
  1195. X/*    struct token *t;
  1196. X/*
  1197. X/*    void tok_flush(t)
  1198. X/*    struct token *t;
  1199. X/*
  1200. X/*    void tok_show(t)
  1201. X/*    struct token *t;
  1202. X/*
  1203. X/*    void put_str(s)
  1204. X/*    char *s;
  1205. X/*
  1206. X/*    void put_ch(c)
  1207. X/*    int c;
  1208. X/*
  1209. X/*    void show_line_control()
  1210. X/*
  1211. X/*    char curr_path[];
  1212. X/*    int curr_line;
  1213. X/* DESCRIPTION
  1214. X/*    These functions read from stdin and write to stdout. The
  1215. X/*    output functions maintain some memory so that two successive
  1216. X/*    words will always be separated by white space.
  1217. X/*
  1218. X/*    The input routines eliminate backslash-newline from the input.
  1219. X/*
  1220. X/*    tok_get() reads the next token from standard input. It returns
  1221. X/*    a null pointer when the end of input is reached. If the skip_flag
  1222. X/*    argument is nonzero, white space (except newline) will be skipped.
  1223. X/*
  1224. X/*    tok_unget() implements a limited amount of token push back.
  1225. X/*
  1226. X/*    tok_show() displays the contents of a (possibly composite) token
  1227. X/*    on the standard output.
  1228. X/*
  1229. X/*    tok_flush() displays the contents of a (possibly composite) token
  1230. X/*    on the standard output and makes it available for re-use.
  1231. X/*
  1232. X/*    put_str() writes a null-terminated string to standard output.
  1233. X/*
  1234. X/*    put_ch() writes one character to standard output.
  1235. X/*
  1236. X/*    show_line_control() displays the line number of the next line
  1237. X/*    to be written to standard output, in a format suitable for the C
  1238. X/*    compiler parser phase.
  1239. X/*
  1240. X/*    The curr_path[] and curr_line variables contain the input file name and 
  1241. X/*    line number of the most recently read token.
  1242. X/* BUGS
  1243. X/*    The tokenizer is just good enough for the unproto filter.
  1244. X/*    As a benefit, it is quite fast.
  1245. X/* AUTHOR(S)
  1246. X/*    Wietse Venema
  1247. X/*    Eindhoven University of Technology
  1248. X/*    Department of Mathematics and Computer Science
  1249. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1250. X/* LAST MODIFICATION
  1251. X/*    91/11/30 21:10:26
  1252. X/* VERSION/RELEASE
  1253. X/*    1.2
  1254. X/*--*/
  1255. X
  1256. Xstatic char io_sccsid[] = "@(#) tok_io.c 1.2 91/11/30 21:10:26";
  1257. X
  1258. X/* C library */
  1259. X
  1260. X#include <stdio.h>
  1261. X#include <ctype.h>
  1262. X
  1263. Xextern char *strchr();
  1264. Xextern char *malloc();
  1265. Xextern char *realloc();
  1266. Xextern char *strcpy();
  1267. X
  1268. X/* Application-specific stuff */
  1269. X
  1270. X#include "token.h"
  1271. X#include "vstring.h"
  1272. X#include "error.h"
  1273. X
  1274. X/* Stuff to keep track of original source file name and position */
  1275. X
  1276. Xchar    curr_path[BUFSIZ];        /* current file name */
  1277. Xint     curr_line = 0;            /* # of last read line */
  1278. X
  1279. X/* Forward declarations */
  1280. X
  1281. Xstatic void read_quoted();
  1282. Xstatic void read_comment();
  1283. X
  1284. X/* Buffered i/o stuff */
  1285. X
  1286. Xstatic struct vstring *buf = 0;        /* read-ahead buffer */
  1287. Xstatic char *bp = "";            /* buffer position */
  1288. X
  1289. X#ifdef DEBUG
  1290. X#define    INITBUF    1            /* small initial buffer size */
  1291. X#else
  1292. X#define    INITBUF BUFSIZ            /* reasonable initial buffer size */
  1293. X#endif
  1294. X
  1295. X#define    input()        (*bp ? *bp++ : next_line())
  1296. X#define    unput(c)    (*--bp = (c))
  1297. X
  1298. X#define    TOK_BUFSIZE    5        /* token push-back buffer size */
  1299. X
  1300. Xstatic struct token *tok_buf[TOK_BUFSIZE];
  1301. Xstatic int tok_bufpos = 0;
  1302. X
  1303. X/* Type of last token sent to output, for pretty printing */
  1304. X
  1305. Xstatic int last_tok = 0;
  1306. X
  1307. X/* Directives that should be ignored. */
  1308. X
  1309. X#ifdef IGNORE_DIRECTIVES
  1310. X
  1311. Xstatic char *ignore_directives[] = {
  1312. X    IGNORE_DIRECTIVES,
  1313. X    0,
  1314. X};
  1315. X
  1316. X#endif
  1317. X
  1318. X/* Modified string and ctype stuff. */
  1319. X
  1320. X#define    STREQUAL(x,y)    (*(x) == *(y) && strcmp((x),(y)) == 0)
  1321. X
  1322. X#define    ISALNUM(c)    (isalnum(c) || (c) == '_')
  1323. X#define    ISALPHA(c)    (isalpha(c) || (c) == '_')
  1324. X#define    ISSPACE(c)    (isspace(c) && c != '\n')
  1325. X#define    ISDOT(c)    (c == '.')
  1326. X
  1327. X/* Collect all characters that satisfy one condition */
  1328. X
  1329. X#define    COLLECT(v,c,cond) { \
  1330. X                register struct vstring *vs = v; \
  1331. X                register char *cp = vs->str; \
  1332. X                *cp++ = c; \
  1333. X                for (;;) { \
  1334. X                    if ((c = input()) == 0) { \
  1335. X                    break; \
  1336. X                    } else if (cond) { \
  1337. X                    if (VS_ADDCH(vs, cp, c) == 0) \
  1338. X                        error(1, "out of memory"); \
  1339. X                    } else { \
  1340. X                    unput(c); \
  1341. X                    break; \
  1342. X                    } \
  1343. X                } \
  1344. X                *cp = 0; \
  1345. X                }
  1346. X
  1347. X/* do_control - parse control line, uses tok_get() */
  1348. X
  1349. Xstatic int do_control()
  1350. X{
  1351. X    struct token *t1;
  1352. X    struct token *t2;
  1353. X    int     pass_thru = 1;        /* 0 = ignore, 1 = output */
  1354. X
  1355. X    (void) input();                /* skip the hash */
  1356. X
  1357. X    if (t1 = tok_get(NO_WSPACE)) {
  1358. X    switch (t1->tokno) {
  1359. X
  1360. X        /*
  1361. X         * In case of line number control, the remainder of the line has
  1362. X         * the format: linenumber "pathname".
  1363. X         */
  1364. X    case TOK_NUMBER:
  1365. X        if (t2 = tok_get(NO_WSPACE)) {
  1366. X        if (t2->tokno == '"') {
  1367. X            curr_line = atoi(t1->vstr->str) - 1;
  1368. X            strcpy(curr_path, t2->vstr->str);
  1369. X        }
  1370. X        tok_free(t2);
  1371. X        }
  1372. X        break;
  1373. X
  1374. X#ifdef IGNORE_DIRECTIVES
  1375. X    case TOK_WORD:
  1376. X        /* Optionally ignore other #directives, such as #pragma. */
  1377. X        {
  1378. X        char  **cpp;
  1379. X        char   *cp = t1->vstr->str;
  1380. X
  1381. X        for (cpp = ignore_directives; *cpp; cpp++) {
  1382. X            if (STREQUAL(cp, *cpp)) {
  1383. X            pass_thru = 0;
  1384. X            break;
  1385. X            }
  1386. X        }
  1387. X        }
  1388. X        break;
  1389. X#endif
  1390. X    }
  1391. X    tok_free(t1);
  1392. X    }
  1393. X    return (pass_thru);
  1394. X}
  1395. X
  1396. X/* next_line - read one logical line, handle #control */
  1397. X
  1398. Xstatic int next_line()
  1399. X{
  1400. X    register int c;
  1401. X    register char *cp;
  1402. X
  1403. X    /* Allocate buffer upon first entry */
  1404. X
  1405. X    if (buf == 0)
  1406. X    buf = vs_alloc(INITBUF);
  1407. X
  1408. X    for (;;) {
  1409. X    cp = buf->str;
  1410. X
  1411. X    /* Account for EOF and line continuations */
  1412. X
  1413. X    while ((c = getchar()) != EOF) {
  1414. X        if (VS_ADDCH(buf, cp, c) == 0)    /* store character */
  1415. X        error(1, "out of memory");
  1416. X        if (c == '\n') {            /* real end of line */
  1417. X        curr_line++;
  1418. X        break;
  1419. X        } else if (c == '\\') {
  1420. X        if ((c = getchar()) == EOF) {    /* XXX strip backslash-EOF */
  1421. X            break;
  1422. X        } else if (c == '\n') {        /* strip backslash-newline */
  1423. X            curr_line++;
  1424. X            put_ch('\n');        /* preserve line count */
  1425. X            cp--;            /* un-store backslash */
  1426. X        } else {
  1427. X            ungetc(c, stdin);        /* keep backslash-other */
  1428. X        }
  1429. X        }
  1430. X    }
  1431. X    *cp = 0;
  1432. X    bp = buf->str;
  1433. X
  1434. X    /* Account for EOF and #control */
  1435. X
  1436. X    switch (bp[0]) {
  1437. X    case 0:                    /* EOF */
  1438. X        return (0);
  1439. X    case '#':                /* control */
  1440. X        if (do_control())
  1441. X        fputs(buf->str, stdout);    /* pass through */
  1442. X        else
  1443. X        putchar('\n');            /* filter out */
  1444. X        break;
  1445. X    default:                /* non-control */
  1446. X        return (input());
  1447. X    }
  1448. X    }
  1449. X}
  1450. X
  1451. X/* tok_unget - push back one token */
  1452. X
  1453. Xvoid    tok_unget(t)
  1454. Xregister struct token *t;
  1455. X{
  1456. X    if (tok_bufpos >= TOK_BUFSIZE)
  1457. X    error(1, "too much pushback");
  1458. X    tok_buf[tok_bufpos++] = t;
  1459. X}
  1460. X
  1461. X/* tok_get - get next token */
  1462. X
  1463. Xstruct token *tok_get(skip_flag)
  1464. Xint     skip_flag;
  1465. X{
  1466. X    register struct token *t;
  1467. X    register int c;
  1468. X    int     d;
  1469. X
  1470. X    /* Use push-back token, if any. */
  1471. X
  1472. X    if (tok_bufpos) {
  1473. X    t = tok_buf[--tok_bufpos];
  1474. X    return (t);
  1475. X    }
  1476. X
  1477. X    /*
  1478. X     * Get one from the pool and fill it in. The loop is here in case we
  1479. X     * should skip white-space tokens, which happens in a minority of all
  1480. X     * cases.
  1481. X     */
  1482. X
  1483. X    t = tok_alloc();
  1484. X
  1485. X    for (;;) {
  1486. X    if ((c = input()) == 0) {
  1487. X        tok_free(t);
  1488. X        return (0);
  1489. X    } else if (!isascii(c)) {
  1490. X        t->vstr->str[0] = c;
  1491. X        t->vstr->str[1] = 0;
  1492. X        t->tokno = TOK_OTHER;
  1493. X        return (t);
  1494. X    } else if (c == '"' || c == '\'') {
  1495. X        read_quoted(t, c);
  1496. X        t->tokno = c;
  1497. X        return (t);
  1498. X    } else if (ISALPHA(c)) {
  1499. X        COLLECT(t->vstr, c, ISALNUM(c));
  1500. X        t->tokno = TOK_WORD;
  1501. X        return (t);
  1502. X    } else if (isdigit(c)) {
  1503. X        COLLECT(t->vstr, c, isdigit(c));
  1504. X        t->tokno = TOK_NUMBER;
  1505. X        return (t);
  1506. X    } else if (ISSPACE(c)) {
  1507. X        COLLECT(t->vstr, c, ISSPACE(c));
  1508. X        if (skip_flag)
  1509. X        continue;
  1510. X        t->tokno = TOK_WSPACE;
  1511. X        return (t);
  1512. X    } else if (ISDOT(c)) {
  1513. X        COLLECT(t->vstr, c, ISDOT(c));
  1514. X        t->tokno = TOK_OTHER;
  1515. X        return (t);
  1516. X    } else {
  1517. X        t->vstr->str[0] = c;
  1518. X        if (c == '/') {
  1519. X        if ((d = input()) == '*') {
  1520. X            t->vstr->str[1] = d;    /* comment */
  1521. X            read_comment(t->vstr);
  1522. X            if (skip_flag)
  1523. X            continue;
  1524. X            t->tokno = TOK_WSPACE;
  1525. X            return (t);
  1526. X        } else {
  1527. X            unput(d);
  1528. X        }
  1529. X        }
  1530. X        t->vstr->str[1] = 0;
  1531. X        t->tokno = c;
  1532. X        return (t);
  1533. X    }
  1534. X    }
  1535. X}
  1536. X
  1537. X/* read_qouted - read string or character literal */
  1538. X
  1539. Xstatic void read_quoted(t, ch)
  1540. Xregister struct token *t;
  1541. Xint     ch;
  1542. X{
  1543. X    register char *cp = t->vstr->str;
  1544. X    register int c;
  1545. X
  1546. X    *cp++ = ch;
  1547. X
  1548. X    while (c = input()) {
  1549. X    if (c == '\n') {            /* newline in string */
  1550. X        unput(c);
  1551. X        break;
  1552. X    }
  1553. X    if (VS_ADDCH(t->vstr, cp, c) == 0)    /* store character */
  1554. X        error(1, "out of memory");
  1555. X    if (c == ch)                /* end of string */
  1556. X        break;
  1557. X    if (c == '\\')                /* eat next character */
  1558. X        if ((c = input()) != 0 && VS_ADDCH(t->vstr, cp, c) == 0)
  1559. X        error(1, "out of memory");
  1560. X    }
  1561. X    *cp = 0;
  1562. X    return;
  1563. X}
  1564. X
  1565. X/* read_comment - stuff a whole comment into one huge token */
  1566. X
  1567. Xstatic void read_comment(vs)
  1568. Xregister struct vstring *vs;
  1569. X{
  1570. X    register char *cp = vs->str + 2;    /* skip slash star */
  1571. X    register int c;
  1572. X    register int d;
  1573. X
  1574. X    while (c = input()) {
  1575. X    if (VS_ADDCH(vs, cp, c) == 0)
  1576. X        error(1, "out of memory");
  1577. X    if (c == '*') {
  1578. X        if ((d = input()) == '/') {
  1579. X        if (VS_ADDCH(vs, cp, d) == 0)
  1580. X            error(1, "out of memory");
  1581. X        break;
  1582. X        } else {
  1583. X        unput(d);
  1584. X        }
  1585. X    }
  1586. X    }
  1587. X    *cp = 0;
  1588. X}
  1589. X
  1590. X/* put_str - output a string */
  1591. X
  1592. Xvoid    put_str(s)
  1593. Xchar   *s;
  1594. X{
  1595. X    fputs(s, stdout);
  1596. X    last_tok = s[0];                /* XXX */
  1597. X#ifdef DEBUG
  1598. X    fflush(stdout);
  1599. X#endif
  1600. X}
  1601. X
  1602. X/* put_ch - put character */
  1603. X
  1604. Xvoid    put_ch(c)
  1605. Xint     c;
  1606. X{
  1607. X    last_tok = putchar(c);
  1608. X#ifdef DEBUG
  1609. X    fflush(stdout);
  1610. X#endif
  1611. X}
  1612. X
  1613. X/* tok_show - output (possibly composite) token */
  1614. X
  1615. Xvoid    tok_show(t)
  1616. Xstruct token *t;
  1617. X{
  1618. X    register struct token *p;
  1619. X    register struct token *s;
  1620. X
  1621. X    switch (t->tokno) {
  1622. X    case TOK_LIST:
  1623. X    for (s = t->head; s; s = s->next) {
  1624. X        put_ch(s->tokno);            /* opening paren or ',' */
  1625. X        for (p = s->head; p; p = p->next)
  1626. X        tok_show(p);
  1627. X    }
  1628. X    put_ch(')');                /* closing paren */
  1629. X    break;
  1630. X    case TOK_WORD:
  1631. X    if (ISALPHA(last_tok))
  1632. X        putchar(' ');
  1633. X    /* FALLTRHOUGH */
  1634. X    default:
  1635. X    fputs(t->vstr->str, stdout);        /* token contents */
  1636. X    last_tok = t->vstr->str[0];
  1637. X#ifdef DEBUG
  1638. X    fflush(stdout);
  1639. X#endif
  1640. X    if (t->head)                /* trailing blanks */
  1641. X            for (p = t->head; p; p = p->next)
  1642. X                tok_show(p);
  1643. X    }
  1644. X}
  1645. END_OF_tok_io.c
  1646. if test 9985 -ne `wc -c <tok_io.c`; then
  1647.     echo shar: \"tok_io.c\" unpacked with wrong size!
  1648. fi
  1649. # end of overwriting check
  1650. fi
  1651. if test -f tok_pool.c -a "${1}" != "-c" ; then 
  1652.   echo shar: Will not over-write existing file \"tok_pool.c\"
  1653. else
  1654. echo shar: Extracting \"tok_pool.c\" \(2184 characters\)
  1655. sed "s/^X//" >tok_pool.c <<'END_OF_tok_pool.c'
  1656. X/*++
  1657. X/* NAME
  1658. X/*    tok_pool 3
  1659. X/* SUMMARY
  1660. X/*    maintain pool of unused token structures
  1661. X/* PACKAGE
  1662. X/*    unproto
  1663. X/* SYNOPSIS
  1664. X/*    #include "token.h"
  1665. X/*
  1666. X/*    struct token *tok_alloc()
  1667. X/*
  1668. X/*    void tok_free(t)
  1669. X/*    struct token *t;
  1670. X/* DESCRIPTION
  1671. X/*    tok_alloc() and tok_free() maintain a pool of unused token
  1672. X/*    structures.
  1673. X/*
  1674. X/*    tok_alloc() takes the first free token structure from the pool
  1675. X/*    or allocates a new one if the pool is empty.
  1676. X/*
  1677. X/*    tok_free() adds a (possibly composite) token structure to the pool.
  1678. X/* BUGS
  1679. X/*    The pool never shrinks.
  1680. X/* AUTHOR(S)
  1681. X/*    Wietse Venema
  1682. X/*    Eindhoven University of Technology
  1683. X/*    Department of Mathematics and Computer Science
  1684. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1685. X/* LAST MODIFICATION
  1686. X/*    91/09/01 23:08:36
  1687. X/* VERSION/RELEASE
  1688. X/*    1.1
  1689. X/*--*/
  1690. X
  1691. Xstatic char pool_sccsid[] = "@(#) tok_pool.c 1.1 91/09/01 23:08:36";
  1692. X
  1693. X/* C library */
  1694. X
  1695. Xextern char *malloc();
  1696. X
  1697. X/* Application-specific stuff */
  1698. X
  1699. X#include "token.h"
  1700. X#include "vstring.h"
  1701. X
  1702. Xextern void error();
  1703. X
  1704. X#define    TOKLEN    5            /* initial string buffer length */
  1705. X
  1706. Xstruct token *tok_pool = 0;        /* free token pool */
  1707. X
  1708. X/* tok_alloc - allocate token structure from pool or heap */
  1709. X
  1710. Xstruct token *tok_alloc()
  1711. X{
  1712. X    register struct token *t;
  1713. X
  1714. X    if (tok_pool) {                /* re-use an old one */
  1715. X    t = tok_pool;
  1716. X    tok_pool = t->next;
  1717. X    } else {                    /* create a new one */
  1718. X    if ((t = (struct token *) malloc(sizeof(struct token))) == 0
  1719. X        || (t->vstr = vs_alloc(TOKLEN)) == 0)
  1720. X        error(1, "out of memory");
  1721. X    }
  1722. X    t->next = t->head = t->tail = 0;
  1723. X#ifdef    DEBUG
  1724. X    strcpy(t->vstr->str, "BUSY");
  1725. X#endif
  1726. X    return (t);
  1727. X}
  1728. X
  1729. X/* tok_free - return (possibly composite) token to pool of free tokens */
  1730. X
  1731. Xvoid    tok_free(t)
  1732. Xregister struct token *t;
  1733. X{
  1734. X#ifdef DEBUG
  1735. X    /* Check if we are freeing free token */
  1736. X
  1737. X    register struct token *p;
  1738. X
  1739. X    for (p = tok_pool; p; p = p->next)
  1740. X    if (p == t)
  1741. X        error(1, "freeing free token");
  1742. X#endif
  1743. X
  1744. X    /* Free neighbours and subordinates first */
  1745. X
  1746. X    if (t->next)
  1747. X    tok_free(t->next);
  1748. X    if (t->head)
  1749. X    tok_free(t->head);
  1750. X
  1751. X    /* Free self */
  1752. X
  1753. X    t->next = tok_pool;
  1754. X    t->head = t->tail = 0;
  1755. X    tok_pool = t;
  1756. X#ifdef    DEBUG
  1757. X    strcpy(t->vstr->str, "FREE");
  1758. X#endif
  1759. X}
  1760. END_OF_tok_pool.c
  1761. if test 2184 -ne `wc -c <tok_pool.c`; then
  1762.     echo shar: \"tok_pool.c\" unpacked with wrong size!
  1763. fi
  1764. # end of overwriting check
  1765. fi
  1766. if test -f token.h -a "${1}" != "-c" ; then 
  1767.   echo shar: Will not over-write existing file \"token.h\"
  1768. else
  1769. echo shar: Extracting \"token.h\" \(1523 characters\)
  1770. sed "s/^X//" >token.h <<'END_OF_token.h'
  1771. X/* @(#) token.h 1.3 91/11/30 21:10:37 */
  1772. X
  1773. Xtypedef struct token {
  1774. X    int     tokno;            /* token value, see below */
  1775. X    int     len;            /* string or list length */
  1776. X    struct vstring *vstr;        /* token contents */
  1777. X    struct token *next;
  1778. X    struct token *head;
  1779. X    struct token *tail;
  1780. X};
  1781. X
  1782. X/* Special token values */
  1783. X
  1784. X#define    TOK_LIST    256        /* () delimited list */
  1785. X#define    TOK_WORD    257        /* keyword or identifier */
  1786. X#define    TOK_NUMBER    258        /* number */
  1787. X#define    TOK_WSPACE    259        /* white space except newline */
  1788. X#define    TOK_OTHER    260        /* other multi-char token */
  1789. X#define    TOK_CONTROL    261        /* flow control keyword */
  1790. X#define    TOK_COMPOSITE    262        /* struct or union */
  1791. X
  1792. X/* Input/output functions and macros */
  1793. X
  1794. Xextern struct token *tok_get();        /* read next single token */
  1795. Xextern void tok_show();            /* display (composite) token */
  1796. Xextern struct token *tok_class();    /* classify tokens */
  1797. Xextern void put_ch();            /* write character */
  1798. Xextern void put_str();            /* write string */
  1799. Xextern void tok_unget();        /* stuff token back into input */
  1800. X
  1801. X#define    tok_flush(t)    (tok_show(t), tok_free(t))
  1802. X
  1803. X/* tok_get() and tok_class() options */
  1804. X
  1805. X#define    DO_WSPACE    0        /* retain space, tab */
  1806. X#define    NO_WSPACE    1        /* skip space, tab */
  1807. X
  1808. X/* Memory management */
  1809. X
  1810. Xstruct token *tok_alloc();        /* allocate token storage */
  1811. Xextern void tok_free();            /* re-cycle storage */
  1812. X
  1813. X/* Context */
  1814. X
  1815. Xextern char curr_path[];        /* current path name */
  1816. Xextern int curr_line;            /* current line number */
  1817. X#define    show_line_control() printf("# %d %s\n", curr_line, curr_path);
  1818. END_OF_token.h
  1819. if test 1523 -ne `wc -c <token.h`; then
  1820.     echo shar: \"token.h\" unpacked with wrong size!
  1821. fi
  1822. # end of overwriting check
  1823. fi
  1824. if test -f unproto.1 -a "${1}" != "-c" ; then 
  1825.   echo shar: Will not over-write existing file \"unproto.1\"
  1826. else
  1827. echo shar: Extracting \"unproto.1\" \(2067 characters\)
  1828. sed "s/^X//" >unproto.1 <<'END_OF_unproto.1'
  1829. X.TH UNPROTO 1 
  1830. X.ad
  1831. X.fi
  1832. X.SH NAME
  1833. Xunproto
  1834. X\-
  1835. XANSI C to old C converter
  1836. X.SH PACKAGE
  1837. X.na
  1838. X.nf
  1839. Xunproto
  1840. X.SH SYNOPSIS
  1841. X.na
  1842. X.nf
  1843. X/lib/cpp ... | unproto
  1844. X
  1845. X/somewhere/cpp ...
  1846. X.SH DESCRIPTION
  1847. X.ad
  1848. X.fi
  1849. XThis document describes a filter that sits between the
  1850. XC preprocessor (usually \fI/lib/cpp\fP) and the next C compiler
  1851. Xpass. It rewrites ANSI-C style function headers, function type
  1852. Xdeclarations, function pointer types, and function pointer casts
  1853. Xto old style. Other ANSI-isms are passed on without modification
  1854. X(token pasting, pragmas, etcetera).
  1855. X
  1856. XFor maximal flexibility, the "cpp | unproto" pipeline can  be
  1857. Xpackaged as an executable shell script named "/somewhere/cpp".
  1858. XThis script should then be specified to the C compiler as a
  1859. Xnon-default preprocessor.
  1860. X
  1861. XThe overhead of shell script interpretation can be avoided by
  1862. Xhaving the unprototyper itself open the pipe to the preprocessor.
  1863. XIn that case, the source should be compiled with the PIPE_THROUGH_CPP
  1864. Xmacro defined (usually as "/lib/cpp"), and the resulting binary
  1865. Xshould be installed as "/somewhere/cpp".
  1866. X.SH SEE ALSO
  1867. X.na
  1868. X.nf
  1869. X.ad
  1870. X.fi
  1871. Xcc(1), how to specify a non-default C preprocessor.
  1872. X
  1873. XSome versions of the lint command are implemented as a shell
  1874. Xscript. It should require only minor modification for integration
  1875. Xwith the unprotoizer. Other versions of the lint command accept the same
  1876. Xcommand syntax as the C compiler for the specification of a non-default
  1877. Xpreprocessor. Some research may be needed.
  1878. X.SH DIAGNOSTICS
  1879. X.ad
  1880. X.fi
  1881. XThe progam will complain if it unexpectedly
  1882. Xreaches the end of input.
  1883. X.SH BUGS
  1884. X.ad
  1885. X.fi
  1886. XShould be run on preprocessed source only, i.e. after macro expansion.
  1887. X
  1888. XDeclarations of (whatever) are misunderstood and will result in
  1889. Xsyntax errors.
  1890. X
  1891. XDoes not generate explicit type casts for function argument
  1892. Xexpressions.
  1893. X.SH AUTHOR(S)
  1894. X.na
  1895. X.nf
  1896. XWietse Venema (wietse@wzv.win.tue.nl)
  1897. XEindhoven University of Technology
  1898. XDepartment of Mathematics and Computer Science
  1899. XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1900. X.SH LAST MODIFICATION
  1901. X.na
  1902. X.nf
  1903. X91/09/22 21:21:35
  1904. X.SH VERSION/RELEASE
  1905. X.na
  1906. X.nf
  1907. X1.2
  1908. END_OF_unproto.1
  1909. if test 2067 -ne `wc -c <unproto.1`; then
  1910.     echo shar: \"unproto.1\" unpacked with wrong size!
  1911. fi
  1912. # end of overwriting check
  1913. fi
  1914. if test -f varargs.c -a "${1}" != "-c" ; then 
  1915.   echo shar: Will not over-write existing file \"varargs.c\"
  1916. else
  1917. echo shar: Extracting \"varargs.c\" \(606 characters\)
  1918. sed "s/^X//" >varargs.c <<'END_OF_varargs.c'
  1919. X /*
  1920. X  * @(#) varargs.c 1.1 91/09/01 23:08:45
  1921. X  * 
  1922. X  * This program can be used to verify that the stdarg.h file is set up
  1923. X  * correctly for your system. If it works, it should print one line with the
  1924. X  * text "stdarg.h works".
  1925. X  */
  1926. X
  1927. X#include <stdio.h>
  1928. X#include "stdarg.h"
  1929. X
  1930. Xmain(int argc, char *argv[])
  1931. X{
  1932. X    varargs_test("%s %s\n", "stdarg.h", "works");
  1933. X}
  1934. X
  1935. Xvarargs_test(char *fmt, ...)
  1936. X{
  1937. X    va_list ap;
  1938. X
  1939. X    va_start(ap, fmt);
  1940. X    while (*fmt) {
  1941. X    if (strncmp("%s", fmt, 2) == 0) {
  1942. X        fputs(va_arg(ap, char *), stdout);
  1943. X        fmt += 2;
  1944. X    } else {
  1945. X        putchar(*fmt);
  1946. X        fmt++;
  1947. X    }
  1948. X    }
  1949. X    va_end(ap);
  1950. X}
  1951. END_OF_varargs.c
  1952. if test 606 -ne `wc -c <varargs.c`; then
  1953.     echo shar: \"varargs.c\" unpacked with wrong size!
  1954. fi
  1955. # end of overwriting check
  1956. fi
  1957. if test -f vstring.c -a "${1}" != "-c" ; then 
  1958.   echo shar: Will not over-write existing file \"vstring.c\"
  1959. else
  1960. echo shar: Extracting \"vstring.c\" \(2328 characters\)
  1961. sed "s/^X//" >vstring.c <<'END_OF_vstring.c'
  1962. X/*++
  1963. X/* NAME
  1964. X/*    vs_alloc(), VS_ADDCH()
  1965. X/* SUMMARY
  1966. X/*    auto-resizing string library
  1967. X/* PACKAGE
  1968. X/*    vstring
  1969. X/* SYNOPSIS
  1970. X/*    #include "vstring.h"
  1971. X/*
  1972. X/*    struct vstring *vs_alloc(len)
  1973. X/*    int len;
  1974. X/*
  1975. X/*    int VS_ADDCH(vs, wp, ch)
  1976. X/*    struct vstring *vs;
  1977. X/*    char *wp;
  1978. X/*    int ch;
  1979. X/* DESCRIPTION
  1980. X/*    These functions and macros implement a small library for
  1981. X/*    arbitrary-length strings that grow automatically when
  1982. X/*    they fill up. The allocation strategy is such that there
  1983. X/*    will always be place for the terminating null character.
  1984. X/*
  1985. X/*    vs_alloc() allocates storage for a variable-length string.
  1986. X/*
  1987. X/*    VS_ADDCH() adds a character to a variable-length string
  1988. X/*    and automagically extends the string if fills up.
  1989. X/*    \fIvs\fP is a pointer to a vstring structure; \fIwp\fP
  1990. X/*    the current write position in the corresponding character
  1991. X/*    array; \fIch\fP the character value to be written.
  1992. X/*    Note that VS_ADDCH() is a macro that evaluates some
  1993. X/*    arguments more than once.
  1994. X/* DIAGNOSTICS
  1995. X/*    VS_ADDCH() returns zero if it was unable to dynamically
  1996. X/*    resize a string.
  1997. X/*
  1998. X/*    vs_alloc() returns a null pointer in case of problems.
  1999. X/* BUGS
  2000. X/*    Auto-resizing may change the address of the string data in
  2001. X/*    a vstring structure. Beware of dangling pointers.
  2002. X/* AUTHOR(S)
  2003. X/*    Wietse Venema
  2004. X/*    Eindhoven University of Technology
  2005. X/*    Department of Mathematics and Computer Science
  2006. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2007. X/* LAST MODIFICATION
  2008. X/*    91/09/22 21:21:38
  2009. X/* VERSION/RELEASE
  2010. X/*    1.2
  2011. X/*--*/
  2012. X
  2013. Xstatic char vstring_sccsid[] = "@(#) vstring.c 1.2 91/09/22 21:21:38";
  2014. X
  2015. X/* C library */
  2016. X
  2017. Xextern char *malloc();
  2018. Xextern char *realloc();
  2019. X
  2020. X/* Application-specific stuff */
  2021. X
  2022. X#include "vstring.h"
  2023. X
  2024. X/* vs_alloc - initial string allocation */
  2025. X
  2026. Xstruct vstring *vs_alloc(len)
  2027. Xint     len;
  2028. X{
  2029. X    register struct vstring *vp;
  2030. X
  2031. X    if (len < 1 
  2032. X    || (vp = (struct vstring *) malloc(sizeof(struct vstring))) == 0
  2033. X    || (vp->str = malloc(len)) == 0)
  2034. X    return (0);
  2035. X    vp->last = vp->str + len - 1;
  2036. X    return (vp);
  2037. X}
  2038. X
  2039. X/* vs_realloc - extend string, update write pointer */
  2040. X
  2041. Xchar   *vs_realloc(vp, cp)
  2042. Xregister struct vstring *vp;
  2043. Xchar   *cp;
  2044. X{
  2045. X    int     where = cp - vp->str;
  2046. X    int     len = vp->last - vp->str + 1;
  2047. X
  2048. X    if ((vp->str = realloc(vp->str, len *= 2)) == 0)
  2049. X    return (0);
  2050. X    vp->last = vp->str + len - 1;
  2051. X    return (vp->str + where);
  2052. X}
  2053. END_OF_vstring.c
  2054. if test 2328 -ne `wc -c <vstring.c`; then
  2055.     echo shar: \"vstring.c\" unpacked with wrong size!
  2056. fi
  2057. # end of overwriting check
  2058. fi
  2059. if test -f vstring.h -a "${1}" != "-c" ; then 
  2060.   echo shar: Will not over-write existing file \"vstring.h\"
  2061. else
  2062. echo shar: Extracting \"vstring.h\" \(410 characters\)
  2063. sed "s/^X//" >vstring.h <<'END_OF_vstring.h'
  2064. X/* @(#) vstring.h 1.1 91/09/01 23:08:42 */
  2065. X
  2066. Xstruct vstring {
  2067. X    char   *str;            /* string value */
  2068. X    char   *last;            /* last position */
  2069. X};
  2070. X
  2071. Xextern struct vstring *vs_alloc();    /* initial allocation */
  2072. Xextern char *vs_realloc();        /* string extension */
  2073. X
  2074. X/* macro to add one character to auto-resized string */
  2075. X
  2076. X#define    VS_ADDCH(vs,wp,c) \
  2077. X    ((wp < (vs)->last || (wp = vs_realloc(vs,wp))) ? (*wp++ = c) : 0)
  2078. END_OF_vstring.h
  2079. if test 410 -ne `wc -c <vstring.h`; then
  2080.     echo shar: \"vstring.h\" unpacked with wrong size!
  2081. fi
  2082. # end of overwriting check
  2083. fi
  2084. echo shar: End of archive 1 \(of 2\).
  2085. cp /dev/null ark1isdone
  2086. MISSING=""
  2087. for I in 1 2 ; do
  2088.     if test ! -f ark${I}isdone ; then
  2089.     MISSING="${MISSING} ${I}"
  2090.     fi
  2091. done
  2092. if test "${MISSING}" = "" ; then
  2093.     echo You have unpacked both archives.
  2094.     rm -f ark[1-9]isdone
  2095. else
  2096.     echo You still need to unpack the following archives:
  2097.     echo "        " ${MISSING}
  2098. fi
  2099. ##  End of shell archive.
  2100. exit 0
  2101.  
  2102. exit 0 # Just in case...
  2103. -- 
  2104. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2105. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2106. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2107. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2108.